<?
/*	Created by Alexander Alexandrov aka SS

			hazg@mail.ru				*/


define('SSLIB_Page', TRUE);

if(!defined("SSLIB_Html")) die("Html class missing");
if(!defined("SSLIB_Request")) die("Request class missing");
if(!defined("SSLIB_Template")) die("Template class missing");
define('SSLIB_PAGE_OBJECT', 'sslib_page_object');
$g_sslib_page_object;


ssinc('compressor');


function P($key, $val, $add = true){Page::Custom($key, $val, $add);}
class ErrPage extends Err
{
	function __construct($message, $code = 0)
	{
		parent::__construct($message, $code);
	}
	function __toString()
	{
		return sslib_exception_format($this->getCode(), $this->getMessage(), $this->getFile(), $this->getLine(), __T('error'),  $this);
	}
}
class Page
{
	private $arr;
	private $templatefile;
	public $title;
	private $description;
	private $keywords;
	private $cssfiles;
	private $jsfiles;
	private $js;
	private $style;
	private $drawed;
	private $lastmodif;
	private $cachepath;
	private $customcachepath;
	
	/*static function ValidateObject()
	{
		global $g_page;
		return empty($g_page)?false:true;
	}*/
	
	private function needCaching()
	{
		return (empty($this->lastmodif)?false:true);
	}
	
	/*private function getCachePath()
	{
		global $sslib_citeroot;
		$str = $_SERVER['REQUEST_URI'];
		if($this->customcachepath)
			$str.=$this->customcachepath;
		foreach($_REQUEST as $k => $v)
		{
			$str.="&$k=$v";
		}
			
		return $sslib_citeroot.'cache/'.md5($str);
	}
	
	private function needUpdate()
	{
		$path = $this->getCachePath();
		if(!file_exists($path))
			return true;
			
		if(filemtime($path) < $this->lastmodif)
			return true;
		return false;
	}
	
	private function saveAndGetCache($arr, $templ)
	{
		$str = Template::CompileFile($arr, $templ);
		
		file_put_contents($this->getCachePath(), gzdeflate($str));
		return $str;	
	}
	
	static function TryFromCache()
	{
		global $g_page;
		
		if($g_page->needCaching() && !$g_page->needUpdate())
		{
			echo gzinflate(file_get_contents($g_page->getCachePath()));
			$g_page->drawed = true;
			exit;
		}
	}*/
	static function getThis()
	{
	    if(array_key_exists(SSLIB_PAGE_OBJECT, $GLOBALS))
	    {
	      //  print 'KEY EXISTS';
	        if(get_class($GLOBALS[SSLIB_PAGE_OBJECT]) === 'Page')
	        {
	        //    print ' CLASS - OK';	
	            return $GLOBALS[SSLIB_PAGE_OBJECT];
	        }
	    }
	    return false;
        //new Err('page does\'t created');	     
	}
	private static function setThis(&$object)
	{
	    if(array_key_exists(SSLIB_PAGE_OBJECT, $GLOBALS) && (get_class($GLOBALS[SSLIB_PAGE_OBJECT]) === 'Page'))
	    {
	        new Err(__T('page object created'));
	    }   
	    
	    $GLOBALS[SSLIB_PAGE_OBJECT] = &$object;
	}
	
	function Page($templatefile, $type = 'text/html'/*, $lastmodif = null, $custompath = null*/)
	{
		if(Page::getThis()!==false) new Err(_('page object created'));
		
		header("Content-type: $type; charset=".Sslib::Variable('page.charset'));
		
		//$this->customcachepath = $custompath;
		$this->drawed = false;
		$this->cachepath = null;
	    
		$this->arr = array();
		
		Page::setThis($this);
		

		$this->Template($templatefile);
		
		ob_start();
	}
	function Template($templatefile = null)
	{
		$g_page = Page::getThis();
		if($templatefile === null) return $g_page->templatefile;
		$g_page->templatefile = Sslib::Variable('site.path').$templatefile;
	}
	function __destruct()
	{
		if(!$this->drawed){new Err(__T("page does't drawed"));}
	}
	function thisDraw()
	{
	    
	    $this->drawed = true;
        $this->_set('content', ob_get_clean(), Page::INSERT_REPLACE);
	    
        $template = Html::Exec(file_get_contents($this->templatefile), $this->templatefile);
		
/*Page::Content(ob_get_clean().
		(Sslib::Debug()?'<div style="text-align:center;position:relative; z-index:1000;margin:2px;padding:2px;background-color: buttonface; border: 1px solid buttonshadow;font:message-box; color: windowtext;">DEBUG MODE</div>':'')
		
		);*/		
		
		//STYLE
		if(!empty($this->style))
			$this->style = '<style type="text/css">'.$this->style.'</style>';
		//JS
		if(!empty($this->js))
			$this->js = "<script type=\"text/javascript\">
			//<![CDATA[<!--
			".$this->js."
			//-->]]>
			</script>";
		//TITLE
		if(!empty($this->title))
			$this->title = '<title>'.$this->title.'</title>';
		//CSS FILES
		
		if(!empty($this->cssfiles))
		{
			/*$cssfiles = split(" ", trim($this->cssfiles));
			$this->cssfiles = "";
			
			foreach($cssfiles as $f)
			{
				if(file_exists(Sslib::CiteRoot($f)))
					$this->cssfiles.=file_get_contents(Sslib::CiteRoot($f));
			}
			if($this->cssfiles != '')
				$this->cssfiles = "<style type=\"text/css\" media=\"screen\"><!--\n$this->cssfiles\n--></style>";*/
		    $this->cssfiles = $this->processCssFiles();
		}
		
		//JS FILES
		if(!empty($this->jsfiles))
		{
			/*
			$jsfiles = split(" ", trim($this->jsfiles));
			$this->jsfiles = "";
			foreach($jsfiles as $f)
			{
			
				if(file_exists(Sslib::SiteRoot($f)))
					$this->jsfiles.= file_get_contents(Sslib::SiteRoot($f));
			}
			if($this->jsfiles != '')
				$this->jsfiles = "<script type=\"text/javascript\">//<--\n$this->jsfiles\n//--></script>";
			*/
		    $this->jsfiles = $this->processJsFiles();
		}
		$this->arr['head'] 
		= "<meta name=\"generator\" content=\"hazg.net\">\n".
		'<meta http-equiv="Content-Type" content="text/html; charset='.Sslib::Variable('page.charset')."\">\n".$this->title."\n".$this->style."\n".$this->cssfiles."\n".$this->jsfiles."\n".$this->js;
		if(!empty($this->description)) $this->arr['head'].='<meta name="description" content="'.$this->description.'">'; 
		if(!empty($this->keywords)) $this->arr['head'].='<meta name="keywords" content="'.$this->keywords.'">';
		
		/*echo "NEED? ".$g_page->needCaching()."<br />";
		echo "UPDATE? ".$g_page->needUpdate();*/
		/*if($this->needCaching() && $this->needUpdate())
		{
			//echo "save to cache";
			echo $this->saveAndGetCache($this->arr, $this->templatefile);
		}
		else*/
		{
			
			
			$template = str_replace('{content}', $this->arr['content'], $template);
			unset($this->content);
			print str_replace(array('{__SS}','{__SE}'), array('<?','?>'), Template::Compile($this->arr, $template));
		}
	}
	static function Draw()
	{
		//header('Content-Type: text/html; charset='.Sslib::Variable('site.charset'));
		$g_page = Page::getThis();
		
		//print_r($g_page);
		if(empty($g_page)) die("Page object does't created!");
		if($g_page->drawed) die("page allready drawed.");
		$g_page->thisDraw();
	}
	const INSERT_REPLACE 	= "0";
	const INSERT_END 		= "1";
	const INSERT_BEGIN 		= "2";
	static function Location($url, $print_link = true)
	{//TODO: Security issue! 
		$url = str_replace(array('<','>','"',"'",'\\'),'',$url); //Done?
		header('Location: '.$url);
		if($print_link){?><div class="sslib_messagebox"><a href="<? print $url; ?>"><? print __T('continue redirection'); ?></a></div><?}
	}
	static function Content		($text, $add = Page::INSERT_REPLACE)	
	{
		Page::Set('content', 	$text, $add);
	}
	static function Title		($text, $add = Page::INSERT_REPLACE)	
	{
		$g_page = Page::getThis();
		switch($add)
		{
			case Page::INSERT_REPLACE:	$g_page->title = $text;break;
			case Page::INSERT_END:		$g_page->title .= $text;break;
			case Page::INSERT_BEGIN:	$g_page->title = $text.$g_page->title;break;
		}
	}
	static function Description($text)
	{
		$g_page = Page::getThis();
		$g_page->description = $text;
	}
	static function Keywords($text)
	{
		$g_page = Page::getThis();
		$g_page->keywords = $text;
	}
	static function JsFile		($text)	
	{
		$g_page = Page::getThis();
		$g_page->jsfiles.=$text." ";
	}
	static function CssFile		($text)	
	{
	    $g_page = Page::getThis();
		$g_page->cssfiles.=$text." ";
	}
	static function Style		($text, $add = Page::INSERT_END)
	{
		$g_page = Page::getThis();
		switch($add)
		{
			case Page::INSERT_REPLACE:	$g_page->style = $text;break;
			case Page::INSERT_END:		$g_page->style .= $text;break;
			case Page::INSERT_BEGIN:	$g_page->style = $text.$g_page->style;break;
		}
	}
	static function JavaScript		($text, $add = Page::INSERT_END)
	{
		$g_page = Page::getThis();
		switch($add)
		{
			case Page::INSERT_REPLACE:	$g_page->js = $text;break;
			case Page::INSERT_END:		$g_page->js .= $text;break;
			case Page::INSERT_BEGIN:	$g_page->js = $text.$g_page->js;break;
		}
	}
	function _set($key, $val, $add = true)
	{
		
		if(strtolower($key) === "head")
			new Err('"Head" is reserved template key!');
		if($add)
		{
			if(isset($this->arr[$key]))
				$this->arr[$key]	.= $val;
			else
				$this->arr[$key]	= $val;
		}
		else 	{	$this->arr[$key]	= $val;		}
	}
	static function Set($key_or_arr, $val = null, $add = true)
	{
		$g_page = Page::getThis();
		if(is_array($key_or_arr) === TRUE)
		{
			foreach ($key_or_arr as $k=>$v)
			{
				$g_page->_set($k, $v, $add);
			}
		}
		else
		{
			$g_page->_set($key_or_arr, $val, $add);
		}
	}
	static function Get($key)
	{
		$g_page = Page::getThis();
		if(array_key_exists($key, $g_page->arr))
			return $g_page->arr[$key];
		return FALSE;
	}
	static function ValidateObject()
	{
	    global $g_page; 
	    
	    return (isset($g_page) && ($g_page !== null) && (get_class($g_page) == 'Page'));
	}
	

    private function processJsFiles()
    {
        
    	$siteroot 		= Sslib::SiteRoot();
    	$md5 			= md5($this->jsfiles);
		
    	$staticJs 		= Sslib::Variable('site.static.js');
    	$staticPath 	= $siteroot.'js/c/'.$md5;
    	$dynamicPath	= $siteroot.'js/';
    	
    	if(file_exists($staticPath) === false || Sslib::Debug())
    	{
    	    
    		$res = '';
            $jsfiles = split(' ', trim($this->jsfiles));
            foreach($jsfiles as $f)
            {
            	$p = $siteroot.$f;
            	if(file_exists($p))
                	$res .= file_get_contents($p)."\n";
            }
            file_put_contents($staticPath, JSCompressor::Process($res));

            exec("gzip $staticPath -c > $staticPath.js");
    	}
        return '<script type="text/javascript" src="'.$staticJs.$md5.'.js"></script>';
    }
    private function processCssFiles()
    {
    	$siteroot 		= Sslib::SiteRoot();
    	$md5 			= md5($this->cssfiles);
    	$staticCss 		= Sslib::Variable('site.static.css');
    	$staticPath 	= $siteroot.'css/c/'.$md5;
    	
    	$dynamicPath	= $siteroot.'css/';
    	
    	if(file_exists($staticPath) === false || Sslib::Debug())
    	{
    		$res = '';
            $cssfiles = split(' ', trim($this->cssfiles));
            foreach($cssfiles as $f)
            {
            	$p = $siteroot.$f;
            	if(is_file($p))
                	$res .= file_get_contents($p)."\n";
            }
            
            $res = str_replace(array("\r\n","\r","\n","\t",'  ','    ','    '),"",preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!','',$res));
            $res = preg_replace('@\s+{@', '{', preg_replace('@([;:,]){1}\s+@', '$1', $res));
            file_put_contents($staticPath, $res);
            exec("gzip $staticPath -c > $staticPath.css");
    	}
        return '<link rel="stylesheet" type="text/css" href="'.$staticCss.$md5.'.css" />';     
    }
	/*static function Expire($arr)
	{
		if(is_array($arr))
		{
			if(array_key_exists('modif', $arr))
				$arr = $arr['modif'];
			else if(array_key_exists('max', $arr))
				$arr = $arr['max'];
			else 
				new Err('$arr is array, but there is no "modif" key!');
		}
		$g_page = Page::getThis();
		
		$arr = strtotime($arr);
		
		if($g_page->lastmodif < $arr)
		{
			$g_page->lastmodif = $arr;
		}
	}*/
	
}
?>